home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 (Walnut Creek) / Aminet - June 1993 [Walnut Creek].iso / usenet / sources / volume2 / iff / iff2sun.1
Text File  |  1988-11-18  |  9KB  |  382 lines

  1. Path: xanth!mcnc!rutgers!mit-eddie!ll-xn!adelie!infinet!ulowell!page
  2. From: page@swan.ulowell.edu (Bob Page)
  3. Newsgroups: comp.sources.amiga
  4. Subject: v02i061:  iff2sun - convert IFF picture files to Sun raster files
  5. Message-ID: <10255@swan.ulowell.edu>
  6. Date: 18 Nov 88 03:01:57 GMT
  7. Organization: University of Lowell, Computer Science Dept.
  8. Lines: 371
  9. Approved: page@swan.ulowell.edu
  10.  
  11. Submitted-by: raz@raster.uucp (Steve Berry)
  12. Posting-number: Volume 2, Issue 61
  13. Archive-name: iff/iff2sun.1
  14.  
  15. Iff2sun will take an IFF picture file and convert it to a Sun raster
  16. file. It's great for making custom backgrounds for Sun workstations.
  17.  
  18. I'm currently at {masscomp,alliant,decvax}raster!raz
  19. But soon: ...alliant!sberry
  20.  
  21. [compile this on a Sun, it's not meant for your Amiga.  ..Bob]
  22.  
  23. #    This is a shell archive.
  24. #    Remove everything above and including the cut line.
  25. #    Then run the rest of the file through sh.
  26. #----cut here-----cut here-----cut here-----cut here----#
  27. #!/bin/sh
  28. # shar:    Shell Archiver
  29. #    Run the following text with /bin/sh to create:
  30. #    iff2sun.c
  31. # This archive created: Thu Nov 17 21:54:29 1988
  32. cat << \SHAR_EOF > iff2sun.c
  33. /*
  34. **      This Program created (under tremendous pressure) by Steve Berry.
  35. **
  36. **      I hope you guys keep it clean. (If you don't, let me know :-)
  37. **
  38. **      Status: PD all the way.
  39. **
  40. **      What's it do? This little guy reads an Amiga IFF ILBM file and 
  41. **      outputs sun rasterfile format. GIGO (Georgous In Garbage Out).
  42. **
  43. **    USEAGE: iff2sun infile outfile
  44. **        if infile is not specified stdin is used.
  45. **        if outfile is not specified then stdout is used.
  46. **
  47. **    Note: this program outputs a COLOR sun file with no color table,
  48. **    which defaults to shades of gray. If you want to display this on
  49. **    a monochrome tube (which is what I have) you should go through the
  50. **    folowing steps:
  51. **        1) iff2sun inputfile outputfile
  52. **        2) rastrepl outputfile output.bigger
  53. **        3) rasfilter8to1 -d output.bigger output.mono
  54. **    The rastrepl just pixel replicates the image so that it large
  55. **    enough to see the detail. you can run this as many times as you
  56. **    like, but remember the image quadruples each time you use it.
  57. **        The rasfilter8to1 program converts the color file (8 bit
  58. **    planes) to mono (1 plane) and does some fancy dithering (-d).
  59. **
  60. **    Limitations:
  61. **        Don't do HAM or ExtraHalfBright. I am planning on adding
  62. **        EHB because it would be relitively simple to do, and 64
  63. **        colors would improve the image quality for the dithering
  64. **        routines.
  65. **        Also, I have only tested this on DPaintII images, it is
  66. **        very possible that it might break with other formats.
  67. **        Unlikely, but possible :*)
  68. **
  69. **    CREDITS:
  70. **            Mark Thompson
  71. **            Steve (Raz) Berry
  72. **
  73. **    Contacts:
  74. **            USENET    ...alliant!sberry
  75. **            BIX:    razberry
  76. **
  77. **      10/31/88
  78. */
  79.  
  80. #include <stdio.h>
  81. #include <rasterfile.h>
  82.  
  83. #define HAM 0x800       /* Amiga Viewmodes */
  84. #define HALF 0x80
  85. #define HIRES 0x8000
  86. #define LACE 0x4
  87. #define TRUE 1
  88. #define FALSE 0
  89.  
  90. /* Stupic C needs to be told about functions used before they
  91.    are defined */
  92.  
  93. unsigned char RGBtoLuma();
  94. long parse();
  95.  
  96. /* Some variables and arrays */
  97.  
  98. unsigned char scanline[500][6][128]; /* vert, planes, width (bytes) */
  99. unsigned char coltable[256];
  100. long width, hieght, planes, viewmode, numcolors;
  101. long temp, compress, i, j, k, l;
  102.  
  103. main(argc,argv)
  104. int argc;
  105. char **argv;
  106. {
  107.     struct rasterfile header;
  108.     unsigned char clr;
  109.     long formsize;
  110.     static char chunk[5];
  111.     FILE *inh, *outh;
  112.         
  113.     chunk[4] = 0;
  114.         
  115.     inh = stdin;
  116.     outh = stdout;
  117.     switch (argc) {
  118.         case 0:
  119.             exit(0);
  120.         case 1:
  121.             break;
  122.         case 2:
  123.             inh = fopen(argv[1],"r");
  124.             break;
  125.         case 3:
  126.             inh = fopen(argv[1],"r");
  127.             outh = fopen(argv[2],"w");
  128.             break;
  129.         default:
  130.             printf("Useage %s: infile outfile, or stdio\n", 
  131.                 argv[0]);
  132.             exit(0);
  133.             break;
  134.     }
  135.         
  136.     if (inh == NULL){
  137.         perror(argv[1]);
  138.         exit(-10);
  139.     }        
  140.  
  141.     if (outh == NULL){
  142.         perror(argv[2]);
  143.         exit(-10);
  144.     }        
  145.  
  146.     /* Now comes the fun part... Reading the ILBM's */
  147.         
  148.     if (parse(inh,"FORM")) {
  149.         perror("I don't think that this is an IFF file");
  150.         exit(-10);
  151.     }
  152.  
  153.     fread(&formsize, 4, 1, inh);    /* length of the FORM */
  154.  
  155.     if (parse(inh,"ILBM")) {
  156.         perror("I don't think that this is an ILBM");
  157.         exit(-10);
  158.     }
  159.  
  160.     if (parse(inh,"BMHD")) { 
  161.         perror("Bad format for ILBM.");
  162.         exit(-10);
  163.     }
  164.  
  165.     cc(chunk);
  166.     fread(chunk, 4, 1, inh);    /* length of the BMHD */
  167.  
  168.     cc(chunk);
  169.     fread(chunk, 2, 1, inh);    /* width of bitmap */
  170.     width = *((short *)chunk);
  171.  
  172.     cc(chunk);
  173.     fread(chunk, 2, 1, inh);    /* Height of bitmap */
  174.     hieght = *((short *)chunk);
  175.  
  176.     fread(chunk, 4, 1, inh);    /* Don't want the orgins */
  177.  
  178.     cc(chunk);
  179.     fread(chunk, 1, 1, inh);    /* # of Planes */
  180.     planes = *((unsigned char *)chunk);
  181.  
  182.     fread(chunk, 1, 1, inh);    /* Ignore the Mask */
  183.  
  184.     cc(chunk);
  185.     fread(chunk, 1, 1, inh);    /* Compression? */
  186.  
  187.     compress = *((unsigned char *)chunk);
  188.  
  189.     fread(chunk, 1, 1, inh);    /* just a pad byte */
  190.  
  191. /***********************************************************************
  192. **    DpaintII does not use the CAMG chunk, so we will have to ignore
  193. **    it for now...
  194. ***********************************************************************/
  195.  
  196.     if (planes == 6) {
  197.         perror("Sorry, I can't do HAM or Halfbright.");
  198.         exit(0);
  199.     } 
  200.  
  201.     if (parse(inh,"CMAP")) {
  202.         perror("Bad format for ILBM, couldn't find Color Map.");
  203.     exit(-10);
  204.     } 
  205.  
  206.     cc(chunk);
  207.     fread(chunk, 4, 1, inh);    /* # of color registers */
  208.     numcolors = *((long *)chunk);
  209.         
  210.     numcolors = numcolors/3 ;
  211.     for (i=0;i<numcolors;i++){
  212.         fread(chunk, 3, 1, inh);
  213.         chunk[3] = 0; chunk[4] = 0; 
  214.         chunk[0] = (chunk[0] >> 4) & 0x0f;
  215.         chunk[2] = (chunk[2] >> 4) & 0x0f;
  216.         chunk[1] = (chunk[1] >> 4) & 0x0f;
  217.         coltable[i] = RGBtoLuma(chunk);
  218.     }
  219.  
  220.     if (numcolors == 2)    /* if a mono image, realign to long word */
  221.         fread(chunk,1,2,inh);
  222.  
  223.     if (parse(inh,"BODY")){
  224.         perror("No BODY data.");
  225.         exit(0);
  226.     }
  227.  
  228.     fread(chunk, 4, 1, inh);    /* length of body */
  229.  
  230.       header.ras_magic= 0x59a66a95;
  231.       header.ras_width= width;
  232.       header.ras_height= hieght;
  233.       header.ras_depth= 8;
  234.       header.ras_length= 0;
  235.       header.ras_type= RT_STANDARD;
  236.       header.ras_maptype= RMT_NONE;
  237.       header.ras_maplength= 0;
  238.  
  239. /* Write out the rasterfile header to the ouput */
  240.  
  241.     fwrite(&header, sizeof(header), 1, outh);
  242.  
  243. /* This part does all the work */
  244.  
  245. /* Either we uncompress the file, or we read it in... */
  246.  
  247.     if (compress == 1)
  248.         uncompress(planes, width, inh);
  249.     else 
  250.         for(k = 0;k<hieght;k++)
  251.             for(i = 0;i<planes;i++) {
  252.                 for(j=0;j<width/8;j++){
  253.                     cc(chunk);
  254.                     if(feof(inh))
  255.                         continue;
  256.                     fread(chunk, 1, 1, inh);
  257.                     scanline[k][i][j] = *((unsigned char *)chunk);
  258.                 }
  259.             }
  260.  
  261. /* Here we take the data and output it (finally!) */
  262.  
  263.     for(j = 0;j<hieght;j++){
  264.         for(i = 0;i<width/8;i++)
  265.             process_pixel(i,j,outh);
  266.     }
  267.     fclose(inh);
  268.     fclose(outh);
  269. } /* end of main */
  270.  
  271. /* The uncompression routine                     */
  272. /* Here we uncompress the data for the number of planes     */
  273. /* and store it in the global array scanline[][][]         */
  274. /* Credits: Leo (the great Caped one) was the originator of the */
  275. /* code I ripped this off from.                 */
  276.  
  277. uncompress(planes, width, inh)
  278. FILE *inh;
  279. long planes, width;
  280. {
  281.     long i,j,count,bytesperrow;
  282.     char len;
  283.     unsigned char byte;
  284.  
  285.     for(i=0;i<hieght;i++){
  286.         for(j=0;j<planes;j++){
  287.             count = 0;
  288.             bytesperrow = width / 8;
  289.             while(bytesperrow > 0){
  290.                 if ((len = getc(inh)) >= 0){
  291.                     bytesperrow -= ++len;
  292.                     fread(&scanline[i][j][count],len,1,inh);
  293.                     count += len;
  294.                 } else if (len == -128)
  295.                     ;
  296.                 else if (len < 0){
  297.                     len = -len + 1;
  298.                     bytesperrow -= len;
  299.                     byte = getc(inh);
  300.                     while(--len >= 0)
  301.                         scanline[i][j][count++] = byte;
  302.                 }
  303.             }
  304.             if(bytesperrow)
  305.                 perror("Compression is messed.");
  306.         }
  307.         
  308.     }
  309. }
  310.  
  311.  
  312. /* RGBtoLuma converts the colortable from the Amiga to Luminance information */
  313. /* This routine was written by Mark Thompson                      */
  314.  
  315. unsigned char RGBtoLuma(color)
  316. unsigned char *color;
  317. {
  318.     unsigned char r, g, b;
  319.     unsigned char grey;
  320.     float fgrey;
  321.  
  322.     r = color[0];
  323.     g = color[1];
  324.     b = color[2];
  325.     fgrey = (0.3 * r + 0.59 * g + 0.11 * b)*16 + 0.5;
  326.     grey = fgrey;
  327.     return grey;
  328. }
  329.  
  330. /* Process the byte for the scanline         */
  331. /* Can you say shift 3 times fast?         */
  332.  
  333. process_pixel(byte,scan,outh)
  334. FILE *outh;
  335. unsigned char byte;
  336. long scan;
  337. {
  338.     long j, i, p, result = 0;
  339.     unsigned char temp;
  340.  
  341.     temp = 0; result = 0;
  342.     for(i=7;i>=0;i--){
  343.         for(p=0;p<planes;p++) 
  344.             result = ((((1 << i) & scanline[scan][p][byte])>>i)<<p) | result;
  345.         result = result & 0x1f;
  346.         temp = coltable[result];
  347.         fwrite(&temp, 1, 1, outh);
  348.         result = 0;
  349.     }
  350. }
  351.  
  352. /* look for a chunk in the file */
  353. long parse(inh, str)
  354. FILE *inh;
  355. char *str;
  356. {
  357.         static char chunk[5];
  358.         chunk[4] = 0;
  359.         while (strncmp(chunk,str,4)!=0){
  360.                 fread(chunk, 4, 1, inh);
  361.                 if(feof(inh)!=0)
  362.                         return TRUE;
  363.         }
  364.         return FALSE;
  365. }
  366.  
  367. /* Clear Chunk variable */
  368.  
  369. cc(chunk)
  370. char chunk[5];
  371. {
  372.     register int i;
  373.     for(i=0;i<5;i++)
  374.         chunk[i] = 0;
  375. }
  376. SHAR_EOF
  377. #    End of shell archive
  378. exit 0
  379. -- 
  380. Bob Page, U of Lowell CS Dept.  page@swan.ulowell.edu  ulowell!page
  381. Have five nice days.
  382.